package models

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

type ResourceRds struct {
	// 阿里云 rds D:\nyy_work\go_path\pkg\mod\github.com\aliyun\alibaba-cloud-sdk-go@v1.62.559\services\rds\struct_db_instance.go

	Model // 不用每次写ID 和 createAt了
	ResourceCommon

	Engine            string `json:"Engine" gorm:"comment:类型有 mysql mariadb postgresql"`
	DBInstanceNetType string `json:"DBInstanceNetType" gorm:"comment:实例的网络连接类型，取值：Internet：外网连接 Intranet：内网连接"`
	DBInstanceClass   string `json:"DBInstanceClass" gorm:"comment:实例的实例规格，取值：rds.mys2.small https://help.aliyun.com/zh/rds/product-overview/primary-apsaradb-rds-instance-types"`
	DBInstanceType    string `json:"DBInstanceType" gorm:"comment:是否主备，Primary：主实例 Readonly：只读实例Guard：灾备实例Temp：临时实例"`
	EngineVersion     string `json:"EngineVersion" gorm:"comment:数据库版本。，取值：8.0 5.7"`
	MasterInstanceId  string `json:"MasterInstanceId" xml:"MasterInstanceId"`
	DBInstanceStatus  string `json:"DBInstanceStatus" xml:"DBInstanceStatus"`
	ReplicateId       string `json:"ReplicateId" xml:"ReplicateId"`

	BindNodes []*StreeNode `json:"bind_nodes" gorm:"many2many:bind_rdss;"` // 多对多
}

// 这里要写上 会变的字段
func (rh *ResourceRds) GenHash() string {
	h := md5.New()
	h.Write([]byte(rh.InstanceId))
	h.Write([]byte(rh.DBInstanceClass))
	h.Write([]byte(rh.EngineVersion))
	return hex.EncodeToString(h.Sum(nil))
}

func (obj *ResourceRds) Create() error {
	return Db.Create(obj).Error

}
func (obj *ResourceRds) DeleteOne() error {

	return Db.Select(clause.Associations).Unscoped().Delete(obj).Error

}

func DeleteResourceRdsOneByInstanceId(iid string) error {

	return Db.Select(clause.Associations).Unscoped().Where("instance_id = ?", iid).Delete(&ResourceRds{}).Error
}

func (obj *ResourceRds) CreateOne() error {
	return Db.Create(obj).Error

}

func (obj *ResourceRds) UpdateOne() error {
	return Db.Where("id = ?", obj.ID).Updates(obj).Error

}

func (obj *ResourceRds) UpdateBindNodes(nodes []*StreeNode) error {

	return Db.Model(obj).Association("BindNodes").Replace(nodes)

}

func GetResourceRdsAll() (objs []*ResourceRds, err error) {
	err = Db.Preload("BindNodes").Find(&objs).Error
	return
}

func GetResourceRdsByLevel(level int) (objs []*ResourceRds, err error) {
	err = Db.Where("level = ?", level).Preload("OpsAdmins").Find(&objs).Error
	return
}

// select * from ecs where
func GetResourceRdsByIdsWithLimitOffset(ids []int, limit, offset int) (objs []*ResourceRds, err error) {
	err = Db.Limit(limit).Offset(offset).Find(&objs, ids).Error
	return
}

func GetResourceRdsByInstanceId(instanceId string) (*ResourceRds, error) {

	var dbObj ResourceRds
	//err := Db.Where("username = ?", userName).Preload("Roles").Joins("Menus").First(&dbUser).Error
	err := Db.Where("instance_id = ?", instanceId).Preload("BindNodes").First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("ResourceRds不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil

}

func GetResourceRdsById(id int) (*ResourceRds, error) {

	var dbObj ResourceRds
	//err := Db.Where("username = ?", userName).Preload("Roles").Joins("Menus").First(&dbUser).Error
	err := Db.Where("id = ?", id).Preload("BindNodes").First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("ResourceRds不存在")
		}
		return nil, fmt.Errorf("数据库错误:%w", err)
	}
	return &dbObj, nil

}

func GetResourceRdsUidAndHash() (map[string]string, error) {

	var objs []*ResourceRds

	err := Db.Find(&objs).Error
	if err != nil {
		return nil, err
	}

	m := make(map[string]string)
	for _, h := range objs {
		m[h.InstanceId] = h.Hash
	}
	return m, nil
}
